/*
    @2023-12-09: 增加宏_ENABLE_OD_ADJUST_定义来控制是否在读出开始前将OD从10V恢复至29V,然后再读出结束后再降至10V.
    @2023-11-09: 将读出相关的代码封装为独立的函数ccd_readout和ccd_exposure. 
*/

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <termios.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <time.h>

#include "REG_BITS.h"
#include "MISC.h"
#include "BONN_SHUTTER.h"

#ifndef _READOUT_H_
#define _READOUT_H_

#define _DEBUG_READOUT_

#define S_IDLE     0
#define S_WAIT     1
#define S_WRITE    2
#define S_DONE     3

// 直接控制AXI/GPIO接口的寄存器，输出一个脉冲给PL端的CCD驱动模块
void Trig_Readout( uint32_t *gpio_reg_ctrl );

void dark_frame_with_abort( float dark_t );

// ccd_readout发出信号驱动CCD读出，并可以根据传递的opt参数决定是否保存图像数据，以及如何保存
int ccd_readout(    uint32_t *gpio_reg_ctrl, 
                    uint32_t *gpio_reg_status, 
                    uint32_t *gpio_reg_pl_ps_ddr_cnt, 
                    uint32_t n_row,
                    uint32_t n_col,
                    int n_bytes,    // 2 for 16bits unsigned; 4 for 32bits float
                    int fast_read_opt,
                    char *filename,
                    int is_master );

int ccd_readout_fp( uint32_t *gpio_reg_ctrl, 
                    uint32_t *gpio_reg_status, 
                    uint32_t *gpio_reg_pl_ps_ddr_cnt, 
                    uint32_t n_row,
                    uint32_t n_col,
                    int n_bytes,    // 2 for 16bits unsigned; 4 for 32bits float
                    int fast_read_opt,
                    char *filename,
                    FILE *fp );

// ccd_exposure在ccd_readout的基础上增加了对快门的控制，其余功能一致
int ccd_exposure(   double t_exp, 
                    uint32_t *gpio_reg_ctrl, 
                    uint32_t *gpio_reg_status, 
                    uint32_t *gpio_reg_pl_ps_ddr_cnt, 
                    uint32_t n_row,
                    uint32_t n_col,
                    int n_bytes,    // 2 for 16bits unsigned; 4 for 32bits float
                    int fast_read_opt,
                    int is_dark,
                    char *filename,
                    char *log_shutter_fname,
                    char *log_camera_fname );

// 在ccd_exposure的基础上增加了中断的功能 added@2024-01-01
// 输入参数中增加MephistoCAM_Config *mcfg，进一步方便参数传递 added@20240427
// int ccd_exposure_with_abort(double t_exp, 
//                             uint32_t *gpio_reg_ctrl, 
//                             uint32_t *gpio_reg_status, 
//                             uint32_t *gpio_reg_pl_ps_ddr_cnt, 
//                             uint32_t n_row,
//                             uint32_t n_col,
//                             int n_bytes,    // 2 for 16bits unsigned; 4 for 32bits float
//                             int fast_read_opt,
//                             int is_dark,
//                             char *filename,
//                             char *log_shutter_fname,
//                             char *log_camera_fname,
//                             MephistoCAM_Config *mcfg );

// 快速刷新,仅作垂直转移
int ccd_refresh(    uint32_t *gpio_reg_ctrl, 
                    uint32_t *gpio_reg_status, 
                    uint32_t *gpio_reg_pl_ps_ddr_cnt, 
                    uint32_t n_row,
                    uint32_t n_col,
                    int n_bytes,    // 2 for 16bits unsigned; 4 for 32bits float
                    int fast_read_opt,
                    char *filename );

int DropCaches( int drop );
int DropCache();

int update_shutter_status( int status, char *fname );
int update_camera_status( int status, char *fname );

void get_gmtime(char gmt_str[32]);
void write_log(FILE *fp, char *log_msg );

void gen_timestamp_op(char gmt_str[26]);

void gen_timestamp_cl(char gmt_str[26]);

double time_diff(struct timeval *start, struct timeval *end);

#endif // _READOUT_H_
